/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package BeanView;

import Clases.ServiceFIAS;
import Dao.DaoAddress;
import HibernateUtil.HibernateUtil;
import Pojo.Address;
import Pojo.Addrobj;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.primefaces.context.RequestContext;

/**
 *
 * @author olegk
 */
@ManagedBean
@ViewScoped
public class MbVAddress implements java.io.Serializable{
    private Session session;
    private Transaction transaction;
    
    private Address address;    
    private ServiceFIAS fias;
    
    private String regionId;
    private String countyId;
    private String districtId;
    private String cityId;
    private String innerCityId;
    private String localityId;
    private String streetId;
    private String addGroundId;
    private String streetAddGroundId;
    private String numAddrLevl1;
    private String typeAddrLevl1;    
    private String numAddrLevl2;
    private String typeAddrLevl2;    
    private String numAddrLevl3;
    private String typeAddrLevl3;    
    private String numApartment;
    private String typeApartment;
    
    private String otherAddress;
        
    @PostConstruct
    public void init() { 
        
        fias = new ServiceFIAS();
                
        address = new Address();
        
        //Object parent=FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("parent");
        //if(parent instanceof Address){
        //    address=(Address)parent;
        //}
        
        for (Entry<String, Addrobj> entry : fias.getRegions().entrySet()) {
            if (entry.getValue().getRegioncode().equals(fias.getDefaultRegion())){
                regionId = entry.getKey();
                onRegionChange();
            }
        }        
    }
    
    public void onRegionChange() {
        if(regionId !=null && !regionId.equals("")){  
            fias.RegionId(regionId);
        }else{
            fias.getCitys().clear();
            fias.getDistricts().clear();
            fias.getCitys().clear();
        }    
    }
    
    public void onDistrictChange() {
        if(districtId !=null && !districtId.equals("")){  
            fias.DistrictId(districtId);
        }else{
            fias.getCitys().clear();
            fias.getInnerCitys().clear();
            fias.getLocalitys().clear();
            onRegionChange();
        }    
    }
    
    public void onCityChange() {
        if(cityId !=null && !cityId.equals("")){ 
            fias.CityId(cityId);
        }else{
            fias.getInnerCitys().clear();
            fias.getLocalitys().clear();
            fias.getStreets().clear();
            onDistrictChange();
        }    
    }
  
    public void onInnerCityChange() {
        if(innerCityId !=null && !innerCityId.equals("")){   
            fias.InnerCityId(innerCityId);
        }else{
            fias.getStreets().clear();
            onCityChange();
        }    
    }
    
    public void onLocalityChange() {
        if(localityId !=null && !localityId.equals("")){   
            fias.LocalityId(localityId);
        }else{
            fias.getStreets().clear();
            fias.getAddGrounds().clear();
            onCityChange();
            onInnerCityChange();
        }    
    }
    
    public void onAddGroundChange() {
        if(addGroundId !=null && !addGroundId.equals("")){
            fias.AddGroundId(addGroundId);
        }else{
            fias.getStreetAddGrounds().clear();
        }    
    }    
     
    public void saveAddress(){ 
        setAddress();        
        RequestContext.getCurrentInstance().closeDialog(this.address);
    }
    
    public void createOtherAddress(){
        setAddress();
        this.otherAddress = address.toString();
    }

    private void setAddress(){
        if (regionId != null) {
            this.address.setFias(getFIASCode(fias.getRegions().get(this.regionId)));
            this.address.setRegion(fias.getRegions().get(this.regionId).getOffname());
            this.address.setRegionType(fias.getRegions().get(this.regionId).getShortname());
            if(fias.getRegions().get(this.regionId).getPostalcode() != null){
                this.address.setPostalCode(fias.getRegions().get(this.regionId).getPostalcode());
            }      
            if(fias.getRegions().get(this.regionId).getOkato() != null){
                this.address.setOkato(fias.getRegions().get(this.regionId).getOkato());
            }
            if(fias.getRegions().get(this.regionId).getOktmo() != null){
                this.address.setOktmo(fias.getRegions().get(this.regionId).getOktmo());
            }
        } 
        if (countyId != null) {
            this.address.setFias(getFIASCode(fias.getCountys().get(this.countyId)));
            this.address.setCounty(fias.getCountys().get(this.countyId).getOffname());
            this.address.setCountyType(fias.getCountys().get(this.countyId).getShortname());
            if(fias.getCountys().get(this.countyId).getPostalcode() != null){
                this.address.setPostalCode(fias.getCountys().get(this.countyId).getPostalcode());
            }
            if(fias.getCountys().get(this.countyId).getOkato() != null){
                this.address.setOkato(fias.getCountys().get(this.countyId).getOkato());
            }
            if(fias.getCountys().get(this.countyId).getOktmo() != null){
                this.address.setOktmo(fias.getCountys().get(this.countyId).getOktmo());
            }
        } 
        if (districtId != null) {
            this.address.setFias(getFIASCode(fias.getDistricts().get(this.districtId)));
            this.address.setDistrict(fias.getDistricts().get(this.districtId).getOffname());
            this.address.setDistrictType(fias.getDistricts().get(this.districtId).getShortname());
            if(fias.getDistricts().get(this.districtId).getPostalcode() != null){
                this.address.setPostalCode(fias.getDistricts().get(this.districtId).getPostalcode());
            }
            if(fias.getDistricts().get(this.districtId).getOkato() != null){
                this.address.setOkato(fias.getDistricts().get(this.districtId).getOkato());
            }
            if(fias.getDistricts().get(this.districtId).getOktmo() != null){
                this.address.setOktmo(fias.getDistricts().get(this.districtId).getOktmo());
            }
        } 
        if (cityId != null) {
            this.address.setFias(getFIASCode(fias.getCitys().get(this.cityId)));
            this.address.setCity(fias.getCitys().get(this.cityId).getOffname());
            this.address.setCityType(fias.getCitys().get(this.cityId).getShortname());
            if(fias.getCitys().get(this.cityId).getPostalcode() != null){
                this.address.setPostalCode(fias.getCitys().get(this.cityId).getPostalcode());
            }
            if(fias.getCitys().get(this.cityId).getOkato() != null){
                this.address.setOkato(fias.getCitys().get(this.cityId).getOkato());
            }
            if(fias.getCitys().get(this.cityId).getOktmo() != null){
                this.address.setOktmo(fias.getCitys().get(this.cityId).getOktmo());
            }
        } 
        if (innerCityId != null) {
            this.address.setFias(getFIASCode(fias.getInnerCitys().get(this.innerCityId)));
            this.address.setInnerCity(fias.getInnerCitys().get(this.innerCityId).getOffname());
            this.address.setInnerCityType(fias.getInnerCitys().get(this.innerCityId).getShortname());
            if(fias.getInnerCitys().get(this.innerCityId).getPostalcode() != null){
                this.address.setPostalCode(fias.getInnerCitys().get(this.innerCityId).getPostalcode());
            }
            if(fias.getInnerCitys().get(this.innerCityId).getOkato() != null){
                this.address.setOkato(fias.getInnerCitys().get(this.innerCityId).getOkato());
            }
            if(fias.getInnerCitys().get(this.innerCityId).getOktmo() != null){
                this.address.setOktmo(fias.getInnerCitys().get(this.innerCityId).getOktmo());
            }
        } 
        if (localityId != null) {
            this.address.setFias(getFIASCode(fias.getLocalitys().get(this.localityId)));
            this.address.setLocality(fias.getLocalitys().get(this.localityId).getOffname());
            this.address.setLocalityType(fias.getLocalitys().get(this.localityId).getShortname());
            if(fias.getLocalitys().get(this.localityId).getPostalcode() != null){
                this.address.setPostalCode(fias.getLocalitys().get(this.localityId).getPostalcode());
            }
            if(fias.getLocalitys().get(this.localityId).getOkato() != null){
                this.address.setOkato(fias.getLocalitys().get(this.localityId).getOkato());
            }
            if(fias.getLocalitys().get(this.localityId).getOktmo() != null){
                this.address.setOktmo(fias.getLocalitys().get(this.localityId).getOktmo());
            }
        } 
        if (streetId != null) {
            this.address.setFias(getFIASCode(fias.getStreets().get(this.streetId)));
            this.address.setStreet(fias.getStreets().get(this.streetId).getOffname());
            this.address.setStreetType(fias.getStreets().get(this.streetId).getShortname());
            if(fias.getStreets().get(this.streetId).getPostalcode() != null){
                this.address.setPostalCode(fias.getStreets().get(this.streetId).getPostalcode());
            }
            if(fias.getStreets().get(this.streetId).getOkato() != null){
                this.address.setOkato(fias.getStreets().get(this.streetId).getOkato());
            }
            if(fias.getStreets().get(this.streetId).getOktmo() != null){
                this.address.setOktmo(fias.getStreets().get(this.streetId).getOktmo());
            }
        } 
        if (addGroundId != null) {
            this.address.setFias(getFIASCode(fias.getAddGrounds().get(this.addGroundId)));
            this.address.setAddGround(fias.getAddGrounds().get(this.addGroundId).getOffname());
            this.address.setAddGroundType(fias.getAddGrounds().get(this.addGroundId).getShortname());
            if(fias.getAddGrounds().get(this.addGroundId).getPostalcode() != null){
                this.address.setPostalCode(fias.getAddGrounds().get(this.addGroundId).getPostalcode());
            }
            if(fias.getAddGrounds().get(this.addGroundId).getOkato() != null){
                this.address.setOkato(fias.getAddGrounds().get(this.addGroundId).getOkato());
            }
            if(fias.getAddGrounds().get(this.addGroundId).getOktmo() != null){
                this.address.setOktmo(fias.getAddGrounds().get(this.addGroundId).getOktmo());
            }
        } 
        if (streetAddGroundId != null) {
            this.address.setFias(getFIASCode(fias.getStreetAddGrounds().get(this.streetAddGroundId)));
            this.address.setStreetAddGround(fias.getStreetAddGrounds().get(this.streetAddGroundId).getOffname());
            this.address.setStreetAddGroundType(fias.getStreetAddGrounds().get(this.streetAddGroundId).getShortname());
            if(fias.getStreetAddGrounds().get(this.streetAddGroundId).getPostalcode() != null){
                this.address.setPostalCode(fias.getStreetAddGrounds().get(this.streetAddGroundId).getPostalcode());
            }
            if(fias.getStreetAddGrounds().get(this.addGroundId).getOkato() != null){
                this.address.setOkato(fias.getStreetAddGrounds().get(this.streetAddGroundId).getOkato());
            }
            if(fias.getStreetAddGrounds().get(this.addGroundId).getOktmo() != null){
                this.address.setOktmo(fias.getStreetAddGrounds().get(this.streetAddGroundId).getOktmo());
            }
        }
        if (!numAddrLevl1.equals("")){  
            this.address.setAddrEl1(numAddrLevl1);
            this.address.setAddrEl1Type(typeAddrLevl1);
        } 
        if (!numAddrLevl2.equals("")){
            this.address.setAddrEl2(numAddrLevl2);
            this.address.setAddrEl2Type(typeAddrLevl2);
        } 
        if (!numAddrLevl3.equals("")){
            this.address.setAddrEl3(numAddrLevl3);
            this.address.setAddrEl3Type(typeAddrLevl3);
        } 
        if (!numApartment.equals("")){
            this.address.setAddrApartment(numApartment);
            this.address.setAddrApartmentType(typeApartment);
        }
        this.address.setAddrMd("");                     //Муниципальное деление
        this.address.setAddrOther(otherAddress);        //Адрес по документам
        this.address.setAddrNote("");        
    }
    
    private String getFIASCode(Addrobj addrobj){
        return addrobj.getRegioncode()+addrobj.getAutocode()+addrobj.getAreacode()+
               addrobj.getCitycode()+addrobj.getCtarcode()+addrobj.getPlacecode()+
               addrobj.getStreetcode()+addrobj.getExtrcode()+addrobj.getSextcode();
    }
    
    private Map<String, Addrobj> AOLevel(String dbQuery) {
        
        this.session=null;
        this.transaction=null;        
        try
        {
            this.session=HibernateUtil.getSessionFactory().openSession();
            this.transaction=session.beginTransaction();
            Query query = session
                .createSQLQuery(dbQuery)
                .addEntity(Addrobj.class); 
            //return query.list();
            Map<String, Addrobj> resultsMap = new HashMap<String, Addrobj>();
            for (Object o : query.list()) {
                Addrobj addr = (Addrobj) o;
                resultsMap.put(addr.getAoguid(), addr);
            }
            return resultsMap;
        }
        catch(Exception ex)
        {
            if(this.transaction!=null)
            {
                this.transaction.rollback();
            }            
            FacesContext.getCurrentInstance().addMessage(null, 
                    new FacesMessage(FacesMessage.SEVERITY_FATAL, 
                                     "Фатальная ошибка:", 
                                     "Пожалуйста, обратитесь к администратору "+
                                     ex.getMessage()));
        }
        finally
        {
            if(this.session!=null)
            {
                this.session.close();
            }
        }
        return null;
    }

    private String FindDefaultRegionCode(String numRegion, Map<String, Addrobj> addr) {
        for (Entry<String, Addrobj> entry : addr.entrySet()) {
            if (entry.getValue().getRegioncode().equals(numRegion)){
                return entry.getKey();
            }
        }
        return null;
    }
    
    private void registration() {
        this.session=null;
        this.transaction=null;
        
        try
        {            
            DaoAddress daoAddress=new DaoAddress();
            this.session=HibernateUtil.getSessionFactory().openSession();
            this.transaction=session.beginTransaction();

            daoAddress.register(this.session, this.address);            
            this.transaction.commit();
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Успех:", "Регистрация прошла успешно"));
        }
        catch(Exception ex)
        {
            if(this.transaction!=null)
            {
                this.transaction.rollback();
            }            
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Фатальная ошибка:", "Пожалуйста, обратитесь к администратору "+ex.getMessage()));
        }
        finally
        {
            if(this.session!=null)
            {
                this.session.close();                
            }
        }
    }
    
    private void update() {
        this.session=null;
        this.transaction=null;
        
        try
        {
            DaoAddress daoAddress=new DaoAddress();            
            this.session=HibernateUtil.getSessionFactory().openSession();
            this.transaction=session.beginTransaction();
            
            daoAddress.update(this.session, this.address);            
            this.transaction.commit();                     
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Успех:", "Изменения были сохранены"));
            this.address=new Address();
            this.address.setId(0L);
        }
        catch(Exception ex)
        {
            if(this.transaction!=null)
            {
                this.transaction.rollback();
            }            
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Фатальная ошибка:", "Пожалуйста, обратитесь к администратору "+ex.getMessage()));
        }
        finally
        {
            if(this.session!=null)
            {
                this.session.close();
            }
        }
    }

    public ServiceFIAS getFias() {
        return fias;
    }
    
    public String getRegionId() {
        return regionId;
    }

    public void setRegionId(String regionId) {
        this.regionId = regionId;
    }

    public String getCountyId() {
        return countyId;
    }

    public void setCountyId(String countyId) {
        this.countyId = countyId;
    }

    public String getDistrictId() {
        return districtId;
    }

    public void setDistrictId(String districtId) {
        this.districtId = districtId;
    }

    public String getCityId() {
        return cityId;
    }

    public void setCityId(String cityId) {
        this.cityId = cityId;
    }

    public String getInnerCityId() {
        return innerCityId;
    }

    public void setInnerCityId(String innerCityId) {
        this.innerCityId = innerCityId;
    }

    public String getLocalityId() {
        return localityId;
    }

    public void setLocalityId(String localityId) {
        this.localityId = localityId;
    }

    public String getStreetId() {
        return streetId;
    }

    public void setStreetId(String streetId) {
        this.streetId = streetId;
    }

    public String getAddGroundId() {
        return addGroundId;
    }

    public void setAddGroundId(String addGroundId) {
        this.addGroundId = addGroundId;
    }

    public String getStreetAddGroundId() {
        return streetAddGroundId;
    }

    public void setStreetAddGroundId(String streetAddGroundId) {
        this.streetAddGroundId = streetAddGroundId;
    }

    public String getNumAddrLevl1() {
        return numAddrLevl1;
    }

    public void setNumAddrLevl1(String numAddrLevl1) {
        this.numAddrLevl1 = numAddrLevl1;
    }

    public String getTypeAddrLevl1() {
        return typeAddrLevl1;
    }

    public void setTypeAddrLevl1(String typeAddrLevl1) {
        this.typeAddrLevl1 = typeAddrLevl1;
    }

    public String getNumAddrLevl2() {
        return numAddrLevl2;
    }

    public void setNumAddrLevl2(String numAddrLevl2) {
        this.numAddrLevl2 = numAddrLevl2;
    }

    public String getTypeAddrLevl2() {
        return typeAddrLevl2;
    }

    public void setTypeAddrLevl2(String typeAddrLevl2) {
        this.typeAddrLevl2 = typeAddrLevl2;
    }

    public String getNumAddrLevl3() {
        return numAddrLevl3;
    }

    public void setNumAddrLevl3(String numAddrLevl3) {
        this.numAddrLevl3 = numAddrLevl3;
    }

    public String getTypeAddrLevl3() {
        return typeAddrLevl3;
    }

    public void setTypeAddrLevl3(String typeAddrLevl3) {
        this.typeAddrLevl3 = typeAddrLevl3;
    }

    public String getNumApartment() {
        return numApartment;
    }

    public void setNumApartment(String numApartment) {
        this.numApartment = numApartment;
    }

    public String getTypeApartment() {
        return typeApartment;
    }

    public void setTypeApartment(String typeApartment) {
        this.typeApartment = typeApartment;
    }

    public String getOtherAddress() {
        return otherAddress;
    }

    public void setOtherAddress(String otherAddress) {
        this.otherAddress = otherAddress;
    }    
}
